iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 7
1
自我挑戰組

白鬍子老頭30天 Swift Ios系列 第 13

Day(7+6) Lecture 7 -1 weak strong unknowed , closures

  • 分享至 

  • xImage
  •  

記憶體管理

swift使用arc (automatic reference counting)
記憶體管理在編譯期間就決定了
每個物件都有個retain count當沒人使用他就會歸0然後物件葛屁

預設是strong retain counting
但是strong有可能會造成記憶體漏失

class Pig {
var myMaster : Owner
deinit{
print("噢不 我要被煮來吃了")
}
}

class Owner {
var myCutePig : Pig
deinit{
print("主人要葛屁了")
}

var peter : Owner = Owner()
var lilRed : Pig = Pig()
peter.myCutePig = lilRed
lilRed.myMaster = peter

peter = nil
lilRed = nil
}

這樣就會造成Reference cycle
因為指定時彼此間是強引用
屬性要等到物件葛屁才會葛屁
但他們互相又有變數指向對方
所以咧~ 無解
一人之豬
直接佔據你的記憶體

解決辦法

使用weak跟unowned兩個關鍵字

weak

鐵石心腸 加了weak的變數retain count是廢票
當這個變數指到的物件死去時會變nil
由於他有可能是nil所以宣告是必須是optional 並且不能是常數(let)

unknowed

跟weak一樣是鐵石心腸 只是當變數指向的物件葛屁後,變數不會變nil
並且可以宣告常數(let)
所以有人存取葛屁的物件就會存取到他的記憶體位置
然後你的app就會崩潰
算是一個危險人物

怎麼選

如果希望是常數選unknowed
如果希望是變數選weak
如果希望它可以是nil 選weak

Closures

closures 也會造成 reference cycle
closures capture value

class Tea {
var name : String
var closureToSaySomething : (()->())!

init (_ teaName : String){
    self.name = teaName
    self.closureToSaySomething = {
    print ("這是"+ self.name + "太好喝了吧")
    }
}
func SayName(){
 closureToSaySomething()
}
deinit {
    print ("倒掉....")
}
}

var moMoTea : Tea = Tea("摸摸茶")
moMoTea = nil

當創造一個摸摸茶時,由於closures capture value,記住了self的記憶體,所以有兩個地方連結到self
一個是宣告的屬性
一個是closureToSaySomething
最後造成一杯倒不掉的摸摸茶

解決辦法

capture list
利用capture list指定特例讓在closures裡的特例變廢票
[//把特例擺在這裡]
Example:

  closureToSaySomething = {
    [weak weakMe = self] in
    print ("這是"+ weakMe.name! + "太好喝了吧")
    }

上一篇
Day(7+5) Lecture 6 FaceitDemo,ViewController Life Cycle
下一篇
Day(7+7) Lecture 7 -2 Extention Protocol Delegation
系列文
白鬍子老頭30天 Swift Ios30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言